package com.fsc.util.socket;

import com.alibaba.fastjson.JSON;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import com.fsc.entity.domain.ChatRecord;
import com.fsc.entity.dto.ChatGetPHistoryDTO;
import com.fsc.entity.dto.ChatPersonMsgDTO;
import com.fsc.entity.vo.PChatRecordVO;
import com.fsc.service.ChatRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

@Component
@Slf4j
public class PersonEventHandler {
    private static final String USER_ID = "userId";
    private static final String GROUP_ID = "groupId";
    @Autowired
    private SocketIOServer socketIOServer;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ChatRecordService chatRecordService;

    @OnConnect
    public void connect(SocketIOClient client){
        // 获取登录信息，也可以在这里面进行权限判断
        String strId = client.getHandshakeData().getSingleUrlParam(USER_ID);
        String strGroupId = client.getHandshakeData().getSingleUrlParam(GROUP_ID);
        Integer userId = Integer.valueOf(strId);
        //暂时不做鉴权限判断
        SocketMap.addClient(userId,client);
        log.info("客户端连接到： userId {}, sessionUuid {}",userId,client.getSessionId());
        //如果是群聊天，处理群聊天
        if(strGroupId!=null){
            Integer groupId = Integer.valueOf(strGroupId);
            log.info("用户加入群聊： userId {}, groupId {}",userId,groupId);
            client.joinRoom(strGroupId);
        }
    }
    @OnDisconnect
    public void disConnect(SocketIOClient client){
        // 获取登录信息
        Integer userId = Integer.valueOf(client.getHandshakeData().getSingleUrlParam(USER_ID));
        String strGroupId = client.getHandshakeData().getSingleUrlParam(GROUP_ID);
        // 移除用户id和客户端连接的绑定
        SocketMap.removeClient(userId);
        log.info("客户端断开连接： userId {}, sessionUuid {}",userId,client.getSessionId());
        if(strGroupId!=null){
            Integer groupId = Integer.valueOf(strGroupId);
            log.info("用户：{} 离开群聊：{}",userId,groupId);
            //用户离开房间
            client.leaveRoom(strGroupId);
        }
    }
    @OnEvent(value = EventConstant.GET_PERSON_HISTORY)
    public void getPersonHistory(SocketIOClient client, String data){
        ChatGetPHistoryDTO chatGetPHistoryDTO = JSON.parseObject(data, ChatGetPHistoryDTO.class);
        log.info("获取私聊记录：{}", chatGetPHistoryDTO);
        List<PChatRecordVO> pChats= chatRecordService.getPHistory(chatGetPHistoryDTO);
        //这里进行了toJson,记得转换成json字符串
        //发送方和接收方都要接收该消息，双方的socket都要订阅该事件
        client.sendEvent(EventConstant.GET_PERSON_HISTORY,JSON.toJSONString(pChats));
    }

    @OnEvent(value = EventConstant.PERSON_MESSAGE)
    public void sendMsg(SocketIOClient client, String data){
        ChatPersonMsgDTO chatPersonMsgDTO= JSON.parseObject(data,ChatPersonMsgDTO.class);

        Integer sendId = chatPersonMsgDTO.getSendId();
        Integer receiveId = chatPersonMsgDTO.getReceiveId();
        log.info("用户： {}  发送私聊消息给：{} ：{}",sendId,receiveId,chatPersonMsgDTO);
        //存储数据
        writeMsgToDb(chatPersonMsgDTO);
        SocketIOClient receiveClient = SocketMap.getClient(receiveId);
        //对方在线直接发送，不在线就不发送
        if(receiveClient!=null){
            receiveClient.sendEvent(EventConstant.PERSON_MESSAGE,data);
        }

    }

    //异步写入数据库
    @Async
    protected void writeMsgToDb(ChatPersonMsgDTO chatPersonMsgDTO){
        ChatRecord chatRecord = ChatRecord.builder()
                .sendId(chatPersonMsgDTO.getSendId())
                .receiveId(chatPersonMsgDTO.getReceiveId())
                .chatType(0)
                .messageType(chatPersonMsgDTO.getMessageType())
                .message(chatPersonMsgDTO.getMessage())
                .voice(chatPersonMsgDTO.getVoice())
                .chatType(0)
                .time(LocalDateTime.now())
                .duration(chatPersonMsgDTO.getDuration())
                .build();
        chatRecordService.save(chatRecord);
    }
}
